#include "map.h"
using namespace mapscreen;



/* infoscreen--------------------------
 * displays the information stored in a
 * fleet.
 * ----------------------------------*/
/*infoscr* infoscr::single = NULL;
//constructors---------------
infoscr* infoscr::gsInfoScr(){
    if(!single){
        builder->get_widget_derived(infoBoxDesig, single);
    }
    return single;
}
infoscr::infoscr(BaseObjectType* obj, const Glib::RefPtr<Gtk::Builder>& window){

}
infoscr::infoscr(){

}
infoscr::~infoscr(){

}
//manips---------------------
void infoscr::draw(){

}*/
/* mapscreen---------------------------
 * This is the map display. handles drawing
 * based on "pixels."  Runs through and
 * stores all the fleets as a pixel, all the
 * terrain, etc, etc.
 * ----------------------------------*/
mapscr* mapscr::single = NULL;
int mapscr::width = 0;
int mapscr::height = 0;
//constructors---------------
mapscr* mapscr::gsMapScr() {
    if (single == NULL) {
        builder->get_widget_derived(mapscrDesig, single);
    }
    return single;
}
mapscr::mapscr(BaseObjectType* obj, const Glib::RefPtr<Gtk::Builder>& window) {
    curp = new cursorpixel();
    cursor[0] = 1;
    cursor[1] = 1;
    offsetX = 0;
    offsetY = 0;
    set_can_focus(true);
    set_double_buffered(true);
}
mapscr::mapscr() {
}
mapscr::~mapscr() {

}
//manips---------------------
void mapscr::draw() {
    int mx = 5, my = 5;
//    mapdata::maprep* m  = mapdata::maprep::getStaticMapRep();
    //m->gSize(mx, my);
    pair<int, int> p;
    //grab the window
    Glib::RefPtr<Gdk::Window> window = get_window();
    if (!window) return;
    Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
    cr->save();
    //window size info
    Gtk::Allocation allocation = get_allocation();
    width = allocation.get_width();
    height = allocation.get_height();

    //paint the bg
    cr->rectangle(0, 0, width, height);
    cr->set_source_rgb(.05, .05, .05);
    cr->fill();

    //paint the lines
    cr->set_source_rgb(0, .7, 0);
    cr->set_line_width(1);
    for (int i = offsetX % pixWid; i < width && i/ pixWid < my; i += pixWid) {
        cr->move_to(i, 0);
        cr->line_to(i, height);
        cr->stroke();
    }
    for (int j = offsetY % pixHgt; j < height && j / pixHgt < mx; j += pixHgt) {
        cr->move_to(0, j);
        cr->line_to(width, j);
        cr->stroke();
    }
    //load the terrain and fleets
    loadFleets();
    loadTerrain();
    //draw pixels
    curp->draw((cursor[0] + offsetX) * pixWid , (cursor[1] + offsetY) * pixHgt, cr);
    for(int i = offsetX / pixWid; i < width / pixWid; i++){
        for(int j = offsetY / pixHgt; j < height / pixHgt; j++){
            if(terrainMap[make_pair(i,j)] != NULL){
                cout << "drawing... " << i << ", " << j << endl;
                terrainMap[make_pair(i,j)]->draw(i, j, cr);
            }
        }
    }

    cr->restore();
}
//load functions-------------
void mapscr::loadFleets() {

}
void mapscr::loadTerrain(){
//    mapdata::maprep* m = mapdata::maprep::getStaticMapRep();
    mapdata::terrain* t = NULL;
    pair<int, int> p;
    for(int i = offsetX / pixWid; i < width / pixWid; i++){
        for(int j = offsetY / pixHgt; j < height / pixHgt; j++){
            p = make_pair(i,j);
            t = NULL;//m->gTerrain(i,j);
            if(t != NULL){
                if(terrainMap[p] != NULL && !terrainMap[p]->compare(t)){
                    cout << "deleting a bad tile" << endl;
                    delete terrainMap[p];
                    terrainMap.erase(terrainMap.find(p));
                } else if ((terrainMap[p] == NULL && t->gType() != mapdata::space)){
                    cout << "loaded terrain " << t->gType() << endl;
                    terrainMap[p] = new terrainpixel(t);
                }
            }
        }
    }
}
//handlers-------------------
bool mapscr::on_key_press_event(GdkEventKey* key) {
    switch(key->keyval){
        case GDK_KEY_Up:
            moveCursor(cursor[0], cursor[1] - 1);
            break;
        case GDK_KEY_Down:
            moveCursor(cursor[0], cursor[1] + 1);
            break;
        case GDK_KEY_Left:
            moveCursor(cursor[0] - 1, cursor[1]);
            break;
        case GDK_KEY_Right:
            moveCursor(cursor[0] + 1, cursor[1]);
            break;
    }
    draw();
    return true;
}
bool mapscr::on_button_press_event(GdkEventButton* btn) {
    return true;
}
bool mapscr::on_expose_event(GdkEventExpose* exp) {
    draw();
    return true;
}

/* Pixels----------------------------------------
 * these classes store representations of each item
 * that needs to be drawn on the map;some need only
 * one representation, while others, like fleetpixel
 * need a more in depth implementation
 * --------------------------------------------*/

//cursor pixel - draws the cursor - we need only one of these
cursorpixel::cursorpixel(){}
void cursorpixel::draw(int x, int y, ctype ct){
    ct->save();
    //set the cursor color
    ct->set_source_rgb(.7,0,0);
    ct->set_line_width(2);
    //ct->set_line_cap(Cairo::LINE_CAP_SQUARE);
    //lower right kerret
    ct->move_to(x + 4, y + (pixHgt / 2) + 4);
    ct->line_to(x + (pixWid / 2) + 4, y + (pixHgt/ 2) + 4);
    ct->line_to(x + (pixWid / 2) + 4, y + 4);
    //upper left kerret
    ct->move_to(x - 4, y - (pixHgt / 2) - 4);
    ct->line_to(x - (pixWid / 2) - 4, y - (pixHgt / 2) -4);
    ct->line_to(x - (pixWid / 2) - 4, y - 4);
    //stroke and return
    ct->stroke();
    ct->restore();
}